use async_trait::async_trait;
use chrono::{Duration, Months, TimeZone, Utc};
use chrono_tz::Asia::Shanghai;
use clap::Parser;

use crate::commands::commands::Command;
use crate::models::models;
use crate::models::models::command::CommandState;
use crate::utils::command;

#[derive(Debug, Default, Clone, Parser)]
#[clap(disable_help_flag = true)]
struct Args {
    #[arg(short = 'y', long = "years", default_value_t = 0, help = "增量年数")]
    years: i64,
    #[arg(short = 'M', long = "months", default_value_t = 0, help = "增量月数")]
    months: i64,
    #[arg(short = 'd', long = "days", default_value_t = 0, help = "增量天数")]
    days: i64,
    #[arg(short = 'h', long = "hours", default_value_t = 0, help = "增量小时")]
    hours: i64,
    #[arg(short = 'm', long = "minutes", default_value_t = 0, help = "增量分钟")]
    minutes: i64,
    #[arg(short = 's', long = "seconds", default_value_t = 0, help = "增量秒")]
    seconds: i64,
    #[arg(short = 'p', long = "parse", default_value = "", help = "从指定的日期时间解析")]
    parse: String,
    #[arg(long = "mil", default_value_t = false, help = "获取毫秒")]
    millis: bool,
    #[arg(long = "mic", default_value_t = false, help = "获取微秒")]
    micros: bool,
    #[arg(long = "sub", default_value_t = false, help = "减去指定的时间增量")]
    sub: bool,
}

#[derive(Debug, Default, Clone)]
pub(crate) struct TimestampCommand {}

#[async_trait]
impl Command for TimestampCommand {
    async fn execute(&self, command: models::command::Command) -> models::command::Command {
        let args = command::parse_command_args::<Args>(command.args.as_str());
        if args.is_err() {
            return self.save_command_output(command, CommandState::Success, args.unwrap_err().to_string());
        }

        let args = args.unwrap();

        // 当前时间
        let mut now = Utc::now().with_timezone(&Shanghai);
        if !args.parse.is_empty() {
            let mut parse = args.parse;
            if !parse.contains(" ") {
                parse = format!("{} 00:00:00", parse.as_str())
            }

            let result = chrono::NaiveDateTime::parse_from_str(parse.as_str(), "%Y-%m-%d %H:%M:%S");
            if result.is_err() {
                return self.save_command_output(command, CommandState::Success, format!("解析日期时间失败: {}", result.unwrap_err().to_string()));
            }

            let result = result.unwrap();
            now = Shanghai.from_local_datetime(&result).unwrap();
        }

        if 0 < args.years { now = if args.sub { now.checked_sub_months(Months::new((12 * args.years) as u32)) } else { now.checked_add_months(Months::new((12 * args.years) as u32)) }.unwrap(); }
        if 0 < args.months { now = if args.sub { now.checked_sub_months(Months::new(args.years as u32)) } else { now.checked_add_months(Months::new(args.years as u32)) }.unwrap(); }
        if 0 < args.days { now = if args.sub { now.checked_sub_signed(Duration::days(args.days)) } else { now.checked_add_signed(Duration::days(args.days)) }.unwrap(); }
        if 0 < args.hours { now = if args.sub { now.checked_sub_signed(Duration::hours(args.hours)) } else { now.checked_add_signed(Duration::hours(args.hours)) }.unwrap(); }
        if 0 < args.minutes { now = if args.sub { now.checked_sub_signed(Duration::minutes(args.minutes)) } else { now.checked_add_signed(Duration::minutes(args.minutes)) }.unwrap(); }
        if 0 < args.seconds { now = if args.sub { now.checked_sub_signed(Duration::seconds(args.seconds)) } else { now.checked_add_signed(Duration::seconds(args.seconds)) }.unwrap(); }

        self.save_command_output(command, CommandState::Success, format!("{}", if args.micros { now.timestamp_micros() } else if args.millis { now.timestamp_millis() } else { now.timestamp() }))
    }
}
